/**
 * 
 */
package mines.fila3.letstalk.data;

import java.util.ArrayList;
import java.util.LinkedList;

import mines.fila3.letstalk.params.LetsTalkConst;
import mines.fila3.letstalk.tools.ThreadPreconditions;
import android.os.Parcel;
import android.os.Parcelable;

/**
 * This class allows to do some operations on the list of messages.
 * 
 * @author aminaud & qmahe
 * 
 */
public class ListMessages implements Parcelable {

	private ArrayList<MessageLetstalk> listMessages;
	private LinkedList<Integer> listNoReadMessages;

	public ListMessages() {

	}

	public ListMessages(Parcel in) {
		in.readTypedList(listMessages, MessageLetstalk.CREATOR);
		in.readList(listNoReadMessages, Integer.class.getClassLoader());
	}

	@Override
	public void writeToParcel(Parcel dest, int flags) {
		dest.writeTypedList(listMessages);
		dest.writeList(listNoReadMessages);
	}

	/**
	 * This method allows to know the size of messages
	 * 
	 * @return number of messages the view will have or have.
	 */
	public int sizeView() {
		if (listMessages == null)
			return -1;
		return listMessages.size();
	}

	/**
	 * To retrieve an item depending on number of items on the view.
	 * 
	 * @param position
	 *              position of the item on the list view.
	 * @return the item from the list of messages.
	 */
	public MessageLetstalk getViewItem(int position) {
		if (position > -1 && position < listMessages.size())
			return listMessages.get(position);
		else
			return null;
	}

	public long getViewItemId(int position) {
		return position;
	}

	/**
	 * 
	 * @param position
	 * @return true if the value "read" of the message has changed.
	 */
	public boolean setReadMessage(int position) {
		MessageLetstalk message = listMessages.get(position);
		if (message.isRead()) {
			return false;
		}
		message.setRead(true);
		listNoReadMessages.remove(Integer.valueOf(position));
		return true;
	}

	public boolean setReadAllMessages() {
		if (listNoReadMessages.size() == 0) {
			return false;
		}

		for (int i : listNoReadMessages) {
			listMessages.get(i).setRead(true);
		}
		listNoReadMessages.clear();

		return true;
	}

	/**
	 * This method allows to update the list of messages: creating a list or
	 * adding new messages. <br>
	 * Here we suppose on the length of the parameter "messages":
	 * <ul>
	 * <li>
	 * "messages" has the same length than our list: no change.</li>
	 * <li>
	 * "messages" have less content than our list: new list of messages.</li>
	 * <li>
	 * "messages" have more content than our list: new messages.</li>
	 * </li>
	 * </ul>
	 * <br>
	 * TODO: if the service can send last and all messages change this method.
	 * 
	 * @param messages
	 *              an array which contains all messages.
	 */
	public boolean updateListMessages(String[] messages) {
		ThreadPreconditions.checkOnMainThread();

		if (listMessages == null || listMessages.size() > messages.length) {
			listMessages = new ArrayList<MessageLetstalk>(messages.length);
			listNoReadMessages = new LinkedList<Integer>();
		} else if (listMessages.size() == messages.length) {
			return false;
		}

		for (int i = listMessages.size(); i < messages.length; i++) {
			String[] messageContent = messages[i].split(LetsTalkConst.MSG_SEPARATOR_INFORMATION, 2);
			if (messageContent.length > 0) {
				MessageLetstalk message;
				if (messageContent.length == 1) {
					message = new MessageLetstalk(messageContent[0], null);
				} else {
					message = new MessageLetstalk(messageContent[0], messageContent[1]);
				}
				listMessages.add(message);
				listNoReadMessages.add(i);
			}
		}

		return true;
	}

	@Override
	public int describeContents() {
		return 0;
	}

	public static final Creator<ListMessages> CREATOR = new Creator<ListMessages>() {

		public ListMessages createFromParcel(Parcel in) {
			return new ListMessages(in);
		}

		public ListMessages[] newArray(int size) {
			return new ListMessages[size];
		}
	};

	public LinkedList<Integer> getListNoReadMessages() {
		return listNoReadMessages;
	}
}
